package org.metasketch.simulator.tools.transactions;

import java.io.File;
import java.io.FileReader;
import java.util.List;
import java.util.Set;

import org.metasketch.demo.model.ActorRole;
import org.metasketch.demo.model.DEMOModel;
import org.metasketch.demo.model.TransactionKind;
import org.metasketch.simulator.petri.PetriNet;
import org.metasketch.simulator.petri.PetriNetSet;
import org.metasketch.simulator.petri.Transition;
import org.metasketch.simulator.resources.Resource;
import org.metasketch.simulator.resources.ResourceBank;
import org.metasketch.simulator.resources.ResourceBase;
import org.metasketch.simulator.resources.ResourceClass;
import org.metasketch.simulator.resources.ResourceRequirements;
import org.metasketch.simulator.tools.Registry;
import org.metasketch.simulator.tools.generic.Expression;
import org.metasketch.simulator.tools.generic.GenericInfo;
import org.metasketch.simulator.tools.generic.GenericInfoValidator;
import org.metasketch.simulator.tools.generic.ResourceProduction;
import org.metasketch.simulator.tools.generic.ResourceRequirement;
import org.metasketch.simulator.tools.generic.Variable;
import org.metasketch.simulator.tools.resources.Alias;
import org.metasketch.simulator.transformation.PetriNetSimulationPackage;

import com.thoughtworks.xstream.XStream;

public class MainTransactionDefinitionLoader {

	protected static XStream getXStream() {
		XStream xstream = new XStream();
		xstream.autodetectAnnotations(true);

		xstream.processAnnotations(Expression.class);
		xstream.processAnnotations(Variable.class);
		xstream.processAnnotations(ResourceRequirement.class);
		xstream.processAnnotations(ResourceProduction.class);

		xstream.processAnnotations(GenericInfo.class);

		xstream.processAnnotations(StepDefinition.class);
		xstream.processAnnotations(Transaction.class);

		// xstream.processAnnotations(Alias.class);

		xstream.processAnnotations(MainTransactions.class);

		return xstream;
	}

	protected static MainTransactions load(File file) throws Throwable {

		XStream xstream = getXStream();

		FileReader reader = new FileReader(file);
		MainTransactions cfg = (MainTransactions) xstream.fromXML(reader);
		reader.close();

		return cfg;

	}

	public static MainTransactions getResources(DEMOModel model,
			PetriNetSimulationPackage simulationPackage, File file)
			throws Throwable {
		MainTransactions cfg = load(file);

		ResourceBank bank = simulationPackage.getResources();
		Registry reg = simulationPackage.getRegistry();
		PetriNetSet petriNetSet = simulationPackage.getPetriNets();

		List<Transaction> transactions = cfg.getTransactions();

		for (Transaction transaction : transactions) {

			// validate steps
			List<StepDefinition> steps = transaction.getSteps();
			for (StepDefinition step : steps) {
				StepDefinitionValidator.validate(step, transaction.getAlias(),
						model, simulationPackage);
			}

			// TODO this will be done outside the loading process, in a separate
			// method.
			// TODO add to register, but associate with the transformed petri
			// nets...weird stuff to do still...hmmm

			// register alias to petri nets...
			// register steps with transition, add atribute "step-alias" and
			// "transaction-alias"

			
			reg.register(transaction.getAlias(), transaction);
			
		}

		return cfg;

	}

}
